﻿using Common;
using DTO;
using ElasticSearch.Core;
using IAccess;
using Nest;
using RobotMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElasticSearchAccess
{
    public class DebugLogAccess : AccessCore<Entity.DebugLog, LogQuery>, IDebugLogAccess
    {
        private BusinessAccess _BusinessAccess = new BusinessAccess();

        public void AddLog(LogRequest logRequest)
        {
            if (logRequest == null || logRequest.Content == null)
                throw new ArgumentException(nameof(logRequest), "日志内容不能为空！");

            //取业务Id 如果没有则新建业务
            var business = _BusinessAccess.IfNotInAddReturnEntity(logRequest.AppId, logRequest.BusinessPosition);
            var entity = new Entity.DebugLog()
            {
                Id = Guid.NewGuid().ToString(),
                Content = logRequest.Content.ToJson(),
                BusinessId = business.Id,
                BusinessPosition = business.BusinessLink,
                PlatformId = business.PlatformId,
                TraceInfo = logRequest.TraceInfo,
                CreationTime = logRequest.CreatTime,
                PlatformName = business.PlatformName,
                RequestId = logRequest.RequestId,
            };
            SearchProvider.Insert(entity);
        }

        public void AddLog(List<LogRequest> logRequests)
        {
            var entities = new List<Entity.DebugLog>();
            foreach (var logRequest in logRequests)
            {
                if (logRequest == null || logRequest.Content == null) continue;

                //取业务Id 如果没有则新建业务
                var business = _BusinessAccess.IfNotInAddReturnEntity(logRequest.AppId, logRequest.BusinessPosition);
                var entity = new Entity.DebugLog()
                {
                    Id = Guid.NewGuid().ToString(),
                    Content = logRequest.Content.ToJson(),
                    BusinessId = business.Id,
                    BusinessPosition = business.BusinessLink,
                    PlatformId = business.PlatformId,
                    TraceInfo = logRequest.TraceInfo,
                    CreationTime = logRequest.CreatTime,
                    PlatformName = business.PlatformName,
                    RequestId = logRequest.RequestId,
                };
                entities.Add(entity);
            }
            SearchProvider.Insert(entities);
        }

        public List<LogInfo> QueryLogRequest(LogQuery query)
        {
            var entities = PageQuery(query);
            return entities.RobotMap<Entity.DebugLog, LogInfo>();
        }

        public long GetTotalCount()
        {
            return SearchProvider.GetTotalCount<Entity.DebugLog>();
        }

        public long GetTodayCount()
        {
            var count = Client.Count<Entity.DebugLog>(s =>
                s.Query(q =>
                    q.DateRange(r =>
                        r.Field(f => f.CreationTime)
                        .GreaterThanOrEquals(DateMath.Anchored(DateTime.Today))
                        .LessThan(DateMath.Anchored(DateTime.Today.AddDays(1)))))).Count;
            return count;
        }

        public void DeleteLog(string id)
        {
            SearchProvider.DeleteById<Entity.DebugLog>(id);
        }

        public void DeleteLog(List<string> ids)
        {
            SearchProvider.DeleteByIds<Entity.DebugLog>(ids);
        }
        
        protected override List<Func<QueryContainerDescriptor<Entity.DebugLog>, QueryContainer>> CreatQueryContainer(LogQuery query)
        {
            var querys = new List<Func<QueryContainerDescriptor<Entity.DebugLog>, QueryContainer>>();

            if (!string.IsNullOrEmpty(query.Content))
                querys.Add(t => t.Wildcard("content.keyword", $"*{query.Content}*"));
            if (!string.IsNullOrEmpty(query.PlatformId))
                querys.Add(s => s.Term("platformId.keyword", query.PlatformId));
            if (!string.IsNullOrEmpty(query.BusinessPosition))
                querys.Add(s => s.Term("businessPosition.keyword", query.BusinessPosition));
            if (!string.IsNullOrEmpty(query.TraceInfo))
                querys.Add(t => t.Wildcard("traceInfo.keyword", $"*{query.TraceInfo}*"));
            if (!string.IsNullOrEmpty(query.RequestId))
                querys.Add(s => s.Term("requestId.keyword", query.RequestId));
            if (query.CreatTimeFrom.HasValue)
            {
                querys.Add(s =>s.DateRange(d=>
                    d.Field(f=>f.CreationTime)
                    .GreaterThanOrEquals(DateMath.Anchored(query.CreatTimeFrom.Value.ToUniversalTime()))));
            }
            if (query.CreatTmeTo.HasValue)
            {
                querys.Add(s => s.DateRange(d =>
                     d.Field(f => f.CreationTime)
                     .LessThan(DateMath.Anchored(query.CreatTmeTo.Value.ToUniversalTime()))));
            }

            return querys;
        }
    }
}
